using System.Collections.Generic;

namespace SharePoint.DataMapper
{
	public static class CamlExtensions
	{
		public static FieldRefExpression Descending(this FieldRefExpression fieldRefExpression)
		{
			fieldRefExpression.Ascending = false;
			return fieldRefExpression;
		}

		public static FieldRefExpression LookupId(this FieldRefExpression fieldRefExpression)
		{
			return new FieldRefExpression(typeof(int), fieldRefExpression.Name, fieldRefExpression.ValueType) {LookupId = true};
		}

		public static LogicalExpression Join(this LogicalExpression left, LogicalOperator @operator, LogicalExpression right)
		{
			return new LogicalExpression(@operator, left, right);
		}

		public static LogicalExpression Join(this FieldRefExpression left, LogicalOperator @operator, FieldExpression fieldExpression)
		{
			return new LogicalExpression(@operator, left, fieldExpression);
		}

		public static LogicalExpression Join(this FieldRefExpression left, LogicalOperator @operator, object value)
		{
			return new LogicalExpression(@operator, left, new ValueExpression(value, left.ValueType));
		}

		public static LogicalExpression Or(this LogicalExpression left, LogicalExpression right)
		{
			return Join(left, LogicalOperator.Or, right);
		}

		public static LogicalExpression And(this LogicalExpression left, LogicalExpression right)
		{
			return Join(left, LogicalOperator.And, right);
		}

		public static LogicalExpression Eq(this FieldRefExpression left, FieldExpression right)
		{
			return Join(left, LogicalOperator.Eq, right);
		}

		public static LogicalExpression Eq(this FieldRefExpression left, object value)
		{
			return Join(left, LogicalOperator.Eq, value);
		}

		public static LogicalExpression Neq(this FieldRefExpression left, FieldExpression right)
		{
			return Join(left, LogicalOperator.Neq, right);
		}

		public static LogicalExpression Neq(this FieldRefExpression left, object value)
		{
			return Join(left, LogicalOperator.Neq, value);
		}

		public static LogicalExpression Lt(this FieldRefExpression left, FieldExpression right)
		{
			return Join(left, LogicalOperator.Lt, right);
		}

		public static LogicalExpression Lt(this FieldRefExpression left, object value)
		{
			return Join(left, LogicalOperator.Lt, value);
		}

		public static LogicalExpression Leq(this FieldRefExpression left, FieldExpression right)
		{
			return Join(left, LogicalOperator.Leq, right);
		}

		public static LogicalExpression Leq(this FieldRefExpression left, object value)
		{
			return Join(left, LogicalOperator.Leq, value);
		}

		public static LogicalExpression Gt(this FieldRefExpression left, FieldExpression right)
		{
			return Join(left, LogicalOperator.Gt, right);
		}

		public static LogicalExpression Gt(this FieldRefExpression left, object value)
		{
			return Join(left, LogicalOperator.Gt, value);
		}

		public static LogicalExpression Geq(this FieldRefExpression left, FieldExpression right)
		{
			return Join(left, LogicalOperator.Geq, right);
		}

		public static LogicalExpression Geq(this FieldRefExpression left, object value)
		{
			return Join(left, LogicalOperator.Geq, value);
		}

		public static LogicalExpression IsNull(this FieldRefExpression left)
		{
			return new LogicalExpression(LogicalOperator.IsNull, left);
		}

		public static LogicalExpression IsNotNull(this FieldRefExpression left)
		{
			return new LogicalExpression(LogicalOperator.IsNotNull, left);
		}

		public static LogicalExpression BeginsWith(this FieldRefExpression left, object value)
		{
			return Join(left, LogicalOperator.BeginsWith, value);
		}

		public static LogicalExpression Contains(this FieldRefExpression left, object value)
		{
			return Join(left, LogicalOperator.Contains, value);
		}

		public static ViewExpression Query(this ViewExpression viewExpression, QueryExpression queryExpression)
		{
			viewExpression.Query = queryExpression;
			return viewExpression;
		}

		public static ViewExpression Query(this ViewExpression viewExpression, WhereExpression whereExpression)
		{
			viewExpression.Query = new QueryExpression(viewExpression.Type, whereExpression, null);
			return viewExpression;
		}

		public static ViewExpression Query(this ViewExpression viewExpression, OrderByExpression orderByExpression)
		{
			viewExpression.Query = new QueryExpression(viewExpression.Type, null, orderByExpression);
			return viewExpression;
		}

		public static ViewExpression Query(this ViewExpression viewExpression, WhereExpression whereExpression, OrderByExpression orderByExpression)
		{
			viewExpression.Query = new QueryExpression(viewExpression.Type, whereExpression, orderByExpression);
			return viewExpression;
		}

		public static ViewExpression ViewFields(this ViewExpression viewExpression, ViewFieldsExpression viewFieldsExpression)
		{
			viewExpression.ViewFields = viewFieldsExpression;
			return viewExpression;
		}

		public static ViewExpression ViewFields(this ViewExpression viewExpression, params FieldRefExpression[] fieldRefExpression)
		{
			viewExpression.ViewFields = new ViewFieldsExpression(fieldRefExpression);
			return viewExpression;
		}

		public static ViewExpression ViewFields(this ViewExpression viewExpression, IEnumerable<FieldRefExpression> fieldRefExpression)
		{
			viewExpression.ViewFields = new ViewFieldsExpression(fieldRefExpression);
			return viewExpression;
		}

		public static ViewExpression RowLimit(this ViewExpression viewExpression, int rowLimit)
		{
			viewExpression.RowLimit = new RowLimitExpression(rowLimit);
			return viewExpression;
		}

		public static ViewExpression Lists(this ViewExpression viewExpression, ListsExpression listsExpression)
		{
			viewExpression.Lists = listsExpression;
			return viewExpression;
		}

		public static ViewExpression Lists(this ViewExpression viewExpression, params ListExpression[] lists)
		{
			viewExpression.Lists = new ListsExpression(lists);
			return viewExpression;
		}

		public static ViewExpression Lists(this ViewExpression viewExpression, IEnumerable<ListExpression> lists)
		{
			viewExpression.Lists = new ListsExpression(lists);
			return viewExpression;
		}

		public static ViewExpression Lists(this ViewExpression viewExpression, int? baseType, int? serverTemplate, int? maxListLimit)
		{
			viewExpression.Lists = new ListsExpression(baseType, serverTemplate, maxListLimit);
			return viewExpression;
		}

		public static ViewExpression Lists(this ViewExpression viewExpression, int? baseType, int? serverTemplate)
		{
			return Lists(viewExpression, baseType, serverTemplate, null);
		}

		public static ViewExpression Webs(this ViewExpression viewExpression, WebsScope scope)
		{
			viewExpression.Webs = new WebsExpression(scope);
			return viewExpression;
		}

		public static ViewExpression Scope(this ViewExpression viewExpression, ViewScope scope)
		{
			viewExpression.Scope = scope;
			return viewExpression;

		}

		public static QueryExpression OrderBy(this QueryExpression queryExpression, params FieldRefExpression[] fieldRefExpression)
		{
			if (queryExpression.OrderBy == null)
			{
				queryExpression.OrderBy = new OrderByExpression(queryExpression.Type, fieldRefExpression);
			}
			else
			{
				queryExpression.OrderBy.Fields.AddRange(fieldRefExpression);
			}
			return queryExpression;
		}

		public static QueryExpression Where(this QueryExpression queryExpression, LogicalExpression logicalExpression)
		{
			queryExpression.Where = new WhereExpression(queryExpression.Type, logicalExpression);
			return queryExpression;
		}
	}
}